#ifndef LEMC_DIALOG_H
#define LEMC_DIALOG_H

#include <list>
#include <algorithm>

#include "guielement.h"

/*
* Class for a dialog. A dialog is a gui container that can contain any type of gui element. A gui element must
* not belong to more than one dialog.
*/
class Dialog
{
private:
	// The list of all elements that belong to the dialog. A gui element must not belong to more than one dialog.
	std::list<GuiElement*> m_element_list;

	// Contains elements to remove in the next update cycle. It is necessary that this is managed with a separate
	// list. Else it could happen that when a button removes itself in a handler, all the iterators get corrupted.
	std::list<std::string> m_elements_to_remove;

public:
	/*
	* Initialized a new dialog.
	*/
	Dialog();

	/*
	* Destroys the dialog removing all its elements. This immediately destroys the elements as in RemoveElement()
	* so this must under no circumstances be called within a gui element handler!
	*/
	~Dialog();

	/*
	* Adds an element to the dialog.
	* 
	* @param element The element to add.
	*/
	void AddElement(GuiElement* element);

	/*
	* Returns whether an element is registered under the given id.
	*
	* @param id The id of the element that is looked up.
	*
	* @return True if the element was found (i.e. belongs to this dialog), else false.
	*/
	bool ElementExists(std::string id);

	/*
	* Gets an element of the dialog by its id.
	*
	* @param id The id of the element that is looked up.
	* @param element The reference to the pointer which should point to the element after a successful get.
	*
	* @return True if the element was found (i.e. belongs to this dialog), else false.
	*/
	bool GetElement(std::string id, GuiElement*& element);

	/*
	* Immediately removes an element to the dialog and deletes it. If the element with the specified it does not   
	* exist, nothing is done. Important: This is not save to use within handler functions of dialog elements or within
	* the elements themselves. It will kill the element immediately, which means severy errors if a element deletes
	* itself and is not completely done with its work.
	* If you want elements to remove themselves or other elements, use 'RemoveElementOnNextUpdate'.
	* 
	* @param id The id of the element to remove and delete.
	*/
	void RemoveElement(std::string id);

	/*
	* Removes an element to the dialog and deletes it. If the element with the specified it does not exist, nothing 
	* is done. Important: This merely adds the element to the elements_to_remove list. It is then deleted on the
	* next update cycle.
	* 
	* @param id The id of the element to remove and delete.
	*/
	void RemoveElementOnNextUpdate(std::string id);

	void PrimaryMouseButtonUp(int x, int y);
	void PrimaryMouseButtonDown(int x, int y);
	void SecondaryMouseButtonUp(int x, int y);
	void SecondaryMouseButtonDown(int x, int y);
	void MouseAxisChange(int x, int y);
	void CharEntered(int keycode, int unichar);

	void Update();
	void Draw();
};

#endif